package edu.gyc.test;

import java.util.concurrent.atomic.AtomicInteger;

public class Counter {

    private static AtomicInteger ai = new AtomicInteger();
    private static int i = 0;

    // 使用CAS实现线程安全的计数器
    public static void safeAdd() {
        //用一个for循环,如果没有计数成功的话,会一直执行这段代码，知道计数成功break为止
        for (; ; ) {
            int j = ai.get();    //读取value值,赋给j,  j在线程的工作内存中
            //将主内存中的值(current)与工作内存中的值j相比较,如果相等的话，说明工作内存中的j值仍然是value的最新值
            //计数运算对当前i操作没有问题,将value值设为j+1,因为value是volatile的，所以写的时候也就写到了主内存
            boolean b = ai.compareAndSet(j, j + 1);
            if (b) {    //如果+1成功
                break;
            }
        }
    }

    // 非安全的线程计数器
    public static void add() {
        i++;
    }

    public static int getI() {
        return i;
    }

    public static void main(String[] args) {
       /*   ExecutorService es = Executors.newCachedThreadPool();
      for(int i=0;i<1000;i++){
            es.execute(new Runnable(){
                @Override
                public void run() {

                    Counter.add();
                    Counter.safeAdd();
                }
            });
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

      */

        for (int i = 0; i < 30; i++) {
            for (int j = 0; j < 1000; j++) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Counter.add();
                        Counter.safeAdd();
                    }
                }).start();
            }

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("i=" + Counter.getI());
            System.out.println("ai=" + ai.get());
        }
    }
}


